package com.fan.gofast.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

    private static String[] parsePatterns = {
            "yyyyMMdd","yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 格式：yyyyMMdd
     */
    public static final String FORMAT_YYYYMMDD = "yyyyMMdd";
    /**
     * 格式：yyMMdd
     */
    public static final String FORMAT_YYMMDD = "yyMMdd";
    /**
     * 格式：yyyy-MM
     */
    public static final String FORMAT_YYYY_MM = "yyyy-MM";
    /**
     * 格式：yyyy-MM-dd
     */
    public static final String FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
    /**
     * 格式：yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    /**
     * 格式：yyyy-MM-dd HH:mm
     */
    public static final String FORMAT_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    /**
     * 格式：yyyyMMddHHmmss
     */
    public static final String FORMAT_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String FORMAT_YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
    /**
     * 格式：yyyyMMddHHmm
     */
    public static final String FORMAT_YYYYMMDDHHMM = "yyyyMMddHHmm";
    /**
     * 格式：HH:mm:ss
     */
    public static final String FORMAT_HH_MM_SS = "HH:mm:ss";
    /**
     * 格式：yyyy
     */
    public static final String FORMAT_YYYY = "yyyy";
    /**
     * 格式：MM
     */
    public static final String FORMAT_MM = "MM";
    /**
     * 格式：dd
     */
    public static final String FORMAT_DD = "dd";
    private static final String dateFormat="yyyy-MM-dd HH:mm:ss";
    private static final String dateFormat1="yyyy-MM-dd";

    private static final String dateFormat2="yyyy-MM-dd HH:mm";
    private static final String dateFormat3="yyyy/MM/dd HH:mm:ss";
    private static final String dateFormat4="yyyy/MM/dd";
    private static final String dateFormat5="yyyy/MM/dd HH:mm";
    private static final String dateFormat6="yyyyMMdd";
    private static final String dateFormatGMT0800="EEE MMM dd yyyy HH:mm:ss 'GMT+0800'";
    private static final String dateFormatGMT="EEE, d MMM yyyy HH:mm:ss 'GMT'";

    /**
     * 获得Date类型当前时间
     *
     * @return
     */
    public static Date getTimestamp() {
        return new Date();
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     */
    public static String getDate() {
        return getDate(FORMAT_YYYY_MM_DD);
    }

    public static Date getDate(Date date) {
        try {
            return parseDate(formatDate(date, FORMAT_YYYY_MM_DD), FORMAT_YYYY_MM_DD);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, String... pattern) {
        String formatDate = null;
        if (date == null) {
            return null;
        }
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, FORMAT_YYYY_MM_DD);
        }
        return formatDate;
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(String strDate, String... pattern) {
        String formatDate = null;
        if (strDate == null) {
            return null;
        }
        Date date = parseDate(strDate);
        if (date == null) {
            return null;
        }
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0]);
        } else {
            formatDate = DateFormatUtils.format(date, FORMAT_YYYY_MM_DD);
        }
        return formatDate;
    }

    /**
     * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, FORMAT_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 得到当前时间字符串 格式（HH:mm:ss）
     */
    public static String getTime() {
        return formatDate(new Date(), FORMAT_HH_MM_SS);
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateTime() {
        return formatDate(new Date(), FORMAT_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getYear() {
        return formatDate(new Date(), FORMAT_YYYY);
    }

    /**
     * 得到当前月份字符串 格式（MM）
     */
    public static String getMonth() {
        return formatDate(new Date(), FORMAT_MM);
    }

    /**
     * 得到当前月份字符串 格式（YYYY_MM）
     */
    public static String getYearMonth() {
        return formatDate(new Date(), FORMAT_YYYY_MM);
    }

    /**
     * 得到当前月份第1天
     *
     * @param pattern 格式（yyyy-MM-dd HH:mm:ss）
     * @return default yyyy-MM-dd
     */
    public static String getFirstDay(String... pattern) {
        Calendar calendar = Calendar.getInstance();
        int num = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, num);
        return formatDate(calendar.getTime(), pattern);
    }

    /**
     * 得到当前月份第1天
     *
     * @return date
     */
    public static Date getFirstDayDate() {
        Calendar calendar = Calendar.getInstance();
        int num = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, num);
        return calendar.getTime();
    }

    /**
     * 得到当前月份最后1天
     *
     * @param pattern 格式（yyyy-MM-dd HH:mm:ss）
     * @return default yyyy-MM-dd
     */
    public static String getLastDay(String... pattern) {
        Calendar calendar = Calendar.getInstance();
        int num = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, num);
        return formatDate(calendar.getTime(), pattern);
    }

    /**
     * 得到当前月份第1天 00点00分00秒
     *
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getFirstDayTime() {
        return String.format("%s %s", getFirstDay(), "00:00:00");
    }

    /**
     * 得到当前月份最后1天 23点59分59秒
     *
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getLastDayTime() {
        return String.format("%s %s", getLastDay(), "23:59:59");
    }

    /**
     * 得到当天字符串 格式（dd）
     */
    public static String getDay() {
        return formatDate(new Date(), FORMAT_DD);
    }

    /**
     * 得到当前星期字符串 格式（E）星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
     * "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 转换为时间（天,时:分:秒.毫秒）
     *
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * @param before
     * @param after
     * @return -1前者小于后者 0前者等于后者 1前者大于后者
     * @Description: 比较两个日期大小
     */
    public static int compareTowDays(Date before, Date after) {
        try {
            if (before.getTime() > after.getTime()) {
                return 1;
            } else if (before.getTime() < after.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     * 1则代表的是对年份操作， 2是对月份操作， 3是对星期操作， 5是对日期操作， 11是对小时操作， 12是对分钟操作， 13是对秒操作，
     * 14是对毫秒操作
     *
     * @param date
     * @param temporalUnit
     * @param amount
     * @return
     */
    private static Date add(Date date, TemporalUnit temporalUnit, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Instant instant = date.toInstant();
            return Date.from(instant.plus(amount, temporalUnit));
        }
    }

    /**
     * 增加天
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addDays(Date date, int amount) {
        return add(date, ChronoUnit.DAYS, amount);
    }

    /**
     * 增加月
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addMonths(Date date, int amount) {
        return localDateTime2Date(date2LocalDateTime(date).plusMonths(amount));
    }

    /***
     * 判断是否为同一天
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDate(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Instant instant = date1.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate().compareTo(date2.toInstant().atZone(zoneId).toLocalDate()) == 0 ? true : false;
    }

    /**
     * Date转换为LocalDateTime
     *
     * @param date
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        if(Objects.isNull(date)){
            return null;
        }
        //An instantaneous point on the time-line.(时间线上的一个瞬时点。)
        Instant instant = date.toInstant();
        //A time-zone ID, such as {@code Europe/Paris}.(时区)
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
		/*DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//This class is immutable and thread-safe.@since 1.8
		System.out.println(dateTimeFormatter.format(localDateTime));//2018-03-27 14:52:57*/
        return localDateTime;
    }

    /**
     * Date转换为date2LocalDate
     *
     * @param date
     */
    public static LocalDate date2LocalDate(Date date) {
        if(Objects.isNull(date)){
            return null;
        }
        //An instantaneous point on the time-line.(时间线上的一个瞬时点。)
        Instant instant = date.toInstant();
        //A time-zone ID, such as {@code Europe/Paris}.(时区)
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate();
    }

    /**
     * LocalDateTime转换为Date
     *
     * @param localDateTime
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        //Combines this date-time with a time-zone to create a  ZonedDateTime.
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 一天的开始
     *
     * @param localDate
     */
    public static Date startOfDay(LocalDate localDate) {
        return localDateTime2Date(localDate.atStartOfDay());
    }

    /**
     * 一天的结束
     *
     * @param localDate
     */
    public static Date endOfDay(LocalDate localDate) {
        return localDateTime2Date(localDate.atTime(LocalTime.MAX));
    }

    /**
     * 时区转换
     *
     * @param time           时间字符串
     * @param pattern        格式 "yyyy-MM-dd HH:mm"
     * @param nowTimeZone    eg:+8，0，+9，-1 等等
     * @param targetTimeZone 同nowTimeZone
     * @param newPattern     格式 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
     * @return
     */
    public static String timeZoneTransfer(String time, String pattern, String nowTimeZone, String targetTimeZone, String newPattern) {
        if (StringUtils.isBlank(time)) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT" + nowTimeZone));
        Date date;
        try {
            date = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            return "";
        }
        simpleDateFormat = new SimpleDateFormat(newPattern);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT" + targetTimeZone));
        return simpleDateFormat.format(date);
    }

   /* public static void main(String[] args) throws ParseException {
        System.out.println(DateUtils.monthDiff(new Date(), addMonths(new Date(), -3)));
        System.out.println(TimeHelper.monthDiff(new Date(), addMonths(new Date(), -3)));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        //System.out.println(dateFormat.parse("2019-05-07 00:00:00"));
        System.out.println(dateFormat.format(new Date()));
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(DateUtils.timeZoneTransfer("2019-05-07 00:00:00", "yyyy-MM-dd HH:mm:ss", "+8", "0", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
        //System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.ENGLISH).format( new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).parse("2019-05-07 00:00:00")));
    }*/

    /**
     * 得到当前年份第1天
     *
     * @return date
     */
    public static Date getFirstDayDateOfYear() {
        Calendar calendar = Calendar.getInstance();
        int num = calendar.getActualMinimum(Calendar.DAY_OF_YEAR);
        calendar.set(Calendar.DAY_OF_YEAR, num);
        return calendar.getTime();
    }

    /**
     * 得到当前年份第1天
     *
     * @param pattern 格式（yyyy-MM-dd HH:mm:ss）
     * @return default yyyy-MM-dd
     */
    public static String getFirstDayOfYear(String... pattern) {
        Calendar calendar = Calendar.getInstance();
        int num = calendar.getActualMinimum(Calendar.DAY_OF_YEAR);
        calendar.set(Calendar.DAY_OF_YEAR, num);
        return formatDate(calendar.getTime(), pattern);
    }

    /**
     * 两个日期间的天数
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static long dayDiff(Date endTime,Date startTime) {
        return ChronoUnit.DAYS.between(endTime.toInstant(), startTime.toInstant());
    }

    /**
     * 两个日期间的分钟数
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static long minutesDiff(Date startTime, Date endTime) {

        return ChronoUnit.MINUTES.between(endTime.toInstant(), startTime.toInstant());
    }

    /**
     * 描述:判断相隔多少月份方法
     **/
    public static int monthDiff(Date startTime, Date endTime) {
        return (int) ChronoUnit.MONTHS.between(date2LocalDate(endTime), date2LocalDate(startTime));
    }

    /**
     * 月初0点
     *
     * @return
     */
    public static Date fristDayOfMonth(Date date) {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDate.from(date.toInstant().atZone(zoneId).toLocalDate().with(TemporalAdjusters.firstDayOfMonth())).atStartOfDay();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 月末23:59:59
     *
     * @return
     */
    public static Date lastDayOfMonth(Date date) {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDate.from(date.toInstant().atZone(zoneId).toLocalDate().with(TemporalAdjusters.lastDayOfMonth())).atTime(LocalTime.MAX);
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * 转localdate
     *
     * @param date
     * @return
     */
    public static LocalDate fromStringDate(String date) {
        return LocalDate.parse(date);
    }

    /**
     * 转localdatetime
     *
     * @param dateTime
     * @return
     */
    public static LocalDateTime fromStringDateTime(String dateTime) {
        return LocalDateTime.parse(dateTime);
    }

    public static LocalDate getFirstDayOfMonth(){
        LocalDate today = LocalDate.now();
        //本月的第一天
        return LocalDate.of(today.getYear(),today.getMonth(),1);
    }




    /**
     * <per>
     * <p>判断日期是否在指定日期区间 ,默认闭区间</p>
     * <per/>
     * @param dateStart
     * @param dateEnd
     * @param data
     * @return boolean
     * @throws
     * @Description : TODO Determining whether the date specified date range . default closed interval
     *                TODO 0: [date Start, date End] | 1: (date Start, date End) | 2:(date Start, date End ] | 3 :[date Start, date End)
     * @author Liruilong
     * @Date 2020/11/5 14:07
     **/
    public static boolean isContainDate(LocalDate dateStart,LocalDate dateEnd, String... data) {
        boolean b = false;
        final LocalDate planDate =LocalDate.parse(data[0]);
        String interval =  data.length > 1 ? data[1]:"0";
        switch (interval){
            case "0":{
                b =  ( planDate.isAfter(dateStart) && planDate.isBefore(dateEnd) )|| planDate.isEqual(dateEnd) || planDate.isEqual(dateStart);
            }break;
            case "1":{
                b =  ( planDate.isAfter(dateStart) && planDate.isBefore(dateEnd) );
            }break;
            case "2":{
                b =  ( planDate.isAfter(dateStart) && planDate.isBefore(dateEnd) ) || planDate.isEqual(dateEnd);
            }break;
            case "3":{
                b =  ( planDate.isAfter(dateStart) && planDate.isBefore(dateEnd) ) || planDate.isEqual(dateStart);
            }break;
            default:break;
        }
        return b;
    }

    /***
     * 判断是否为日期
     * @param mes
     * @return
     */
    public static boolean isRqSjFormat(String mes){
        Pattern pattern = Pattern
                .compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-9]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
        Matcher matcher = pattern.matcher(mes);
        if (matcher.matches()) {
            return true;
        } else {
            return false;
        }
    }

    public static Date convert(String source){
        if (StringUtils.isBlank(source)){
            return null;
        }
        source=source.trim();
        try{
            ZoneId zoneId=ZoneId.systemDefault();
            DateTimeFormatter formatter=null;
            if (source.contains("-")){
                if (source.contains(":")){
                    if ((source.length()-source.replace(":", "").length())>1){
                        formatter=DateTimeFormatter.ofPattern(dateFormat);
                        return Date.from(LocalDateTime.parse(source, formatter).atZone(zoneId).toInstant());
                    } else{
                        formatter=DateTimeFormatter.ofPattern(dateFormat2);
                        return Date.from(LocalDateTime.parse(source, formatter).atZone(zoneId).toInstant());
                    }
                } else{
                    formatter=DateTimeFormatter.ofPattern(dateFormat1);
                    return Date.from(LocalDate.parse(source, formatter).atStartOfDay(zoneId).toInstant());
                }
            } else if (source.contains("/")){
                if (source.contains(":")){
                    if ((source.length()-source.replace(":", "").length())>1){
                        formatter= DateTimeFormatter.ofPattern(dateFormat3);
                        return Date.from(LocalDateTime.parse(source, formatter).atZone(zoneId).toInstant());
                    } else{
                        formatter=DateTimeFormatter.ofPattern(dateFormat5);
                        return Date.from(LocalDateTime.parse(source, formatter).atZone(zoneId).toInstant());
                    }
                } else{
                    formatter=DateTimeFormatter.ofPattern(dateFormat4);
                    return Date.from(LocalDate.parse(source, formatter).atStartOfDay(zoneId).toInstant());
                }

            } else if (source.length()==8&&isNumber(source)){
                formatter=DateTimeFormatter.ofPattern(dateFormat6);
                return Date.from(LocalDate.parse(source, formatter).atStartOfDay(zoneId).toInstant());
            } else if (source.contains("GMT")){
                if (source.contains("GMT+0800")){
                    return Date.from(LocalDateTime.parse(source, DateTimeFormatter.ofPattern(dateFormatGMT0800, Locale.ENGLISH)).atZone(zoneId).toInstant());
                } else{
                    return Date.from(LocalDateTime.parse(source, DateTimeFormatter.ofPattern(dateFormatGMT, Locale.ENGLISH)).atZone(zoneId).toInstant());
                }
            }

        } catch (Exception e){
            throw new RuntimeException(String.format("parser %s to Date fail", source));
        }
        return null;
    }
    public static boolean isNumber(String text) {
        if (StringUtils.isEmpty(text))
            return false;
        return text.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
    }

    public static int compareLocalDate(Date date2) {
        LocalDate localDate = LocalDateTimeUtil.parseDate(DateUtil.format(date2, DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_DATE_PATTERN);
        return LocalDate.now().compareTo(localDate);
    }

    public static int compareLocalDate(Date date1,Date date2) {
        LocalDate localDateBefore = LocalDateTimeUtil.parseDate(DateUtil.format(date1, DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_DATE_PATTERN);
        LocalDate localDate = LocalDateTimeUtil.parseDate(DateUtil.format(date2, DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_DATE_PATTERN);
        return localDateBefore.compareTo(localDate);
    }

    public static void main(String[] args) {
//        LocalDate localDateBefore = LocalDateTimeUtil.parseDate("2023-04-14",DatePattern.NORM_DATE_PATTERN);
//        LocalDate localDate = LocalDateTimeUtil.parseDate("2023-04-15",DatePattern.NORM_DATE_PATTERN);
//        System.out.println(localDateBefore.compareTo(localDate));
        System.out.println(compareLocalDate(DateUtil.parseDate("2023-04-31")));
    }

}
